#include "astroscene.h"
#include <QGraphicsSceneMouseEvent>
#include <math.h>
#include <QPainter>

astroScene::astroScene(QObject* parent):QGraphicsScene(parent)
{
    nStarCount = 0;
}

void astroScene::mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent)
{
    QGraphicsScene::mousePressEvent(mouseEvent);
    emit sigMouse(mouseEvent->pos());

    int x = mouseEvent->pos().x();
    int y = mouseEvent->pos().y();
    for(int i=-3; i<4; i++)
        for(int j=-3;j<4; j++)
        {
            QRgb pix = image.pixel(x+i,y+j);
            emit sigRGB(i+3, j+3, pix);
        }
}

void astroScene::Search()
{
    copyImage = image;
    noise = 0;
    int nCount = 0;
    for(int i=3; i<copyImage.width()-3; i++)
    {
        for(int j=3; j<copyImage.height()-3; j++)
        {
            noise += PixelIntensity(copyImage.pixel(i,j));
            nCount++;
        }
    }
    noise /= nCount;
    noise *= 10.0;

    for(int i=3; i<copyImage.width()-3; i++)
    {
        //qDebug("Checking row %d", i);
        QString stat;
        stat.sprintf("Checking %d", i);
        emit sigStatus(stat);
        for(int j=3; j<copyImage.height()-3; j++)
        {
            if( PixelIntensity(copyImage.pixel(i,j))>noise && SpotIntensity(i,j)>noise )
            {
                // see if brightest of 8 nearest neighbors
                /*if( PixelIntensity(image.pixel(i-1,j-1)) > intensity )
                    continue;
                if( PixelIntensity(image.pixel(i-1,j)) > intensity )
                    continue;
                if( PixelIntensity(image.pixel(i-1,j+1)) > intensity )
                    continue;

                if( PixelIntensity(image.pixel(i+1,j-1)) > intensity )
                    continue;
                if( PixelIntensity(image.pixel(i+1,j)) > intensity )
                    continue;
                if( PixelIntensity(image.pixel(i+1,j+1)) > intensity )
                    continue;

                if( PixelIntensity(image.pixel(i,j-1)) > intensity )
                    continue;
                if( PixelIntensity(image.pixel(i,j+1)) > intensity )
                    continue;
*/
                // got brightest pixel

                int pixLeft = i-1;
                int pixRight = i+1;
                int pixTop = j-1;
                int pixBottom = j+1;
                bool bExpanded = false;

                do
                {
                   // qDebug("Expanding (%d, %d)-(%d, %d)",pixTop, pixLeft, pixBottom, pixRight);
                    bExpanded = false;
                    // check 8 pixels to see if any neighbors are bright enough

                    // first check along left edge from +/-1 of top and bottom to see if need to expand left
                    if( pixLeft>3 && CheckRow(pixLeft-1, pixLeft-1, pixTop, pixBottom) )
                    {
                        pixLeft--;
                        bExpanded = true;
                    }

                    // check right edge
                    if( pixRight<copyImage.width()-3 && CheckRow(pixRight+1, pixRight+1, pixTop, pixBottom) )
                    {
                        pixRight++;
                        bExpanded = true;
                    }

                    // check top edge
                    if( pixTop>3 && CheckRow(pixLeft, pixRight, pixTop-1, pixTop-1) )
                    {
                        pixTop--;
                        bExpanded = true;
                    }

                    // check bottom edge
                    if( pixBottom<copyImage.height()-3 && CheckRow(pixLeft, pixRight, pixBottom+1, pixBottom+1) )
                    {
                        pixBottom++;
                        bExpanded = true;
                    }

                }while( bExpanded );

                QPainter qPainter(&image);
                qPainter.setBrush(Qt::NoBrush);
                qPainter.setPen(Qt::red);
                qPainter.drawRect(pixLeft,pixTop,pixRight-pixLeft,pixBottom-pixTop);
                bool bEnd = qPainter.end();

                QPainter qPainter2(&copyImage);
                qPainter2.setBrush(Qt::black);
                qPainter2.setPen(Qt::black);
                qPainter2.drawRect(pixLeft,pixTop,pixRight-pixLeft,pixBottom-pixTop);
                bEnd = qPainter2.end();

                qDebug("Star at %d, %d", i,j);
                nStarCount++;
                emit sigStarCount(nStarCount);
                emit sigStar((pixLeft+pixRight)/2, (pixTop+pixBottom)/2);
            }
        }
    }
}

bool astroScene::CheckRow(int i1, int i2, int j1, int j2)
{
    for(int i=i1; i<=i2; i++)
        for(int j=j1; j<=j2; j++)
            if( PixelIntensity(copyImage.pixel(i,j))>noise )
                return true;

    return false;
}

double astroScene::SpotIntensity(int i, int j)
{
    double averageIntensity =   PixelIntensity(copyImage.pixel(i-1,j-1)) +
                                PixelIntensity(copyImage.pixel(i-1,j)) +
                                PixelIntensity(copyImage.pixel(i-1,j+1)) +
                                PixelIntensity(copyImage.pixel(i,j-1)) +
                                PixelIntensity(copyImage.pixel(i,j)) +
                                PixelIntensity(copyImage.pixel(i,j+1)) +
                                PixelIntensity(copyImage.pixel(i+1,j-1)) +
                                PixelIntensity(copyImage.pixel(i+1,j)) +
                                PixelIntensity(copyImage.pixel(i+1,j+1));
    return averageIntensity / 9.0;

}

double astroScene::PixelIntensity(QRgb pixel)
{
    double r=qRed(pixel);
    double g=qGreen(pixel);
    double b=qBlue(pixel);
    return sqrt(r*r+g*g+b*b);
}

void astroScene::Load(QString filename)
{
    strFilename = filename;
    emit sigfile(strFilename);
    qp.load(filename);
    image = qp.toImage();
    Search();
    qp = qp.fromImage(image);
}

void astroScene::Info()
{
    emit sigfile(strFilename);
    emit sigStarCount(nStarCount);
}
